package com.artup.util.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.artup.util.json.JsonValidator;

/**
 * @Title: HttpClient.java
 * @Description: <p>封装httpCilent请求类</p>
 * @author 李滨
 * @date 2016-09-23 下午2:24:03   
 * @version v 1.0 
 */
@SuppressWarnings("deprecation")
@Component
public class HttpClientUtil {
	private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);

	@Autowired
    HttpConnectionManager httpConnectionManager;
    
	public static final String CONTENT_CHARSET = "UTF-8";
	public static final String CONTENT_TYPE_JSON_CHARSET = "application/json;charset=utf-8";
	public static final String USER_AGENT = "Mozilla/5.0 (X11; Ubuntu; Linux i686; zh-CN; rv:1.9.1.2) Gecko/20090803";
	 /**
	   * 设置HttpMethod通用配置
	   * 
	   * @param httpMethod
	   */
	  public static void setCommonHttpMethod(HttpRequestBase httpMethod) {
	    httpMethod.setHeader(HTTP.CONTENT_ENCODING, CONTENT_CHARSET);
	    httpMethod.setHeader(HTTP.USER_AGENT, USER_AGENT);
	    //httpMethod.setHeader(HTTP.CHARSET_PARAM, CONTENT_CHARSET);
	    //httpMethod.setHeader(HTTP.CONTENT_TYPE, CONTENT_TYPE_JSON_CHARSET);
	  }
	  
	  /**
	   * 构造get请求参数
	   * @param url 请求URL路径
	   * @param params get请求参数
	   * @return
	   */
	  private static String buildGetUrl(String url, Map<String, String> params) {
		    StringBuffer uriStr = new StringBuffer(url);
		    if (params != null) {
		      List<NameValuePair> ps = new ArrayList<NameValuePair>();
		      for (String key : params.keySet()) {
		        ps.add(new BasicNameValuePair(key, params.get(key)));
		      }
		      uriStr.append("?");
		      uriStr.append(URLEncodedUtils.format(ps, CONTENT_CHARSET));
		    }
		    return uriStr.toString();
	  }
	  /**
	   * 构造post 请求参数
	   * @param url 请求URL路径
	   * @param params post请求参数
	   * @return
	   */
	  public static HttpPost buildHttpPost(String url, Map<String, String> params)
		      throws UnsupportedEncodingException, URISyntaxException {
		    HttpPost post = new HttpPost(url);
		    setCommonHttpMethod(post);
		    HttpEntity he = null;
		    if (params != null) {
		      List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		      for (String key : params.keySet()) {
		        formparams.add(new BasicNameValuePair(key, params.get(key)));
		      }
		      he = new UrlEncodedFormEntity(formparams, CONTENT_CHARSET);
		      post.setEntity(he);
		    }
		    return post;
	  }
	  
	/**
	 * 封装 Http get请求 
	 * @param path 请求URL路径
	 * @param params post请求参数
	 * @param clazz 返回类型
	 * @return 返回指定类型对象
	 */
	public <T> T get(String url,Map<String, String> params,Class<T> clazz){
        CloseableHttpClient httpClient=httpConnectionManager.getHttpClient();
        
        HttpGet httpget = new HttpGet(buildGetUrl(url,params));
    	
        //httpget.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 180000);		// 设置“请求超时时间”
        //httpget.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);		// 设置“读取超时时间”
        RequestConfig
        requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(180000).build();
        httpget.setConfig(requestConfig);
        
        String json=null;        
        CloseableHttpResponse response=null;
        try {
            response = httpClient.execute(httpget);
            InputStream in=response.getEntity().getContent();
            json=IOUtils.toString(in, CONTENT_CHARSET);
            in.close();
            if(StringUtils.isBlank(json)) {
    			return null;
    		}
            LOGGER.info("HTTP Response Result = " + json);
        } catch (UnsupportedOperationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {            
            if(response!=null){
            	try {
            		response.close();
            	} catch (IOException e) {
            		e.printStackTrace();
            	}
            }            
        }
        if(new JsonValidator().validate(json)) {
			return JSONObject.parseObject(json, clazz);
		} else {
			return null;
		}
        //return JSON.parseObject(json, clazz);
    }

	/**
	 * 获取 Map
	 * @param url
	 * @param params
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Object> getMap(String url, Map<String, String> parameterMap){
		CloseableHttpClient httpClient = httpConnectionManager.getHttpClient();
		
		url = buildGetUrl(url, parameterMap);
		System.out.println("url = " + url);
		HttpGet httpGet = new HttpGet(url);
		
		//httpGet.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 180000);		// 设置“请求超时时间”
		//httpGet.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);
		RequestConfig
        requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(180000).build();
        httpGet.setConfig(requestConfig);
		CloseableHttpResponse closeableHttpResponse = null;
		try {
			closeableHttpResponse = httpClient.execute(httpGet);
		} catch (ClientProtocolException e) {
			LOGGER.error("执行 HTTP GET 请求 - 失败：", e);
		} catch (IOException e) {
			LOGGER.error("执行 HTTP GET 请求 - 失败：", e);
		}
		
		if(null == closeableHttpResponse) {
			return null;
		}
		
		InputStream inputStream = null;
		
		try {
			inputStream = closeableHttpResponse.getEntity().getContent();
		} catch (UnsupportedOperationException e) {
			LOGGER.error("执行 HTTP GET 请求 - 失败：", e);
		} catch (IOException e) {
			LOGGER.error("输入输出异常：", e);
		}         
		
		if(null == inputStream) {
			return null;
		}
		
		String result = null;

		try {
			result = IOUtils.toString(inputStream, CONTENT_CHARSET);
		} catch (IOException e) {
			LOGGER.error("转换 HTTP 响应数据 - 失败！", e);
		}
		
		if(null != inputStream) {
			try {
				inputStream.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 输入流 - 失败：", e);
			}
		}
		if(null != closeableHttpResponse){
			try {
				closeableHttpResponse.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 响应信息 - 失败：", e);
			}
		}  
		
		if(StringUtils.isBlank(result)) {
			return null;
		}
		
		LOGGER.info("HTTP Response Result = " + result);
		
		if(new JsonValidator().validate(result)) {
			return JSON.parseObject(result, Map.class);
		} else {
			return null;
		}
	}

	/**
	 * 获取数组
	 * @param url
	 * @param params
	 * @param object
	 * @return
	 */
	public Object getArray(String url, Map<String, String> params, Class<?> object){
		CloseableHttpClient httpClient = httpConnectionManager.getHttpClient();
		HttpGet httpGet = new HttpGet(buildGetUrl(url,params));
		
		//httpGet.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 180000);		// 设置“请求超时时间”
		//httpGet.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);
		RequestConfig
        requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(180000).build();
        httpGet.setConfig(requestConfig);
		CloseableHttpResponse closeableHttpResponse = null;
		try {
			closeableHttpResponse = httpClient.execute(httpGet);
		} catch (ClientProtocolException e) {
			LOGGER.error("执行 HTTP GET 请求 - 失败：", e);
		} catch (IOException e) {
			LOGGER.error("执行 HTTP GET 请求 - 失败：", e);
		}
		
		if(null == closeableHttpResponse) {
			return null;
		}
		
		InputStream inputStream = null;
		
		try {
			inputStream = closeableHttpResponse.getEntity().getContent();
		} catch (UnsupportedOperationException e) {
			LOGGER.error("执行 HTTP GET 请求 - 失败：", e);
		} catch (IOException e) {
			LOGGER.error("输入输出异常：", e);
		}         
		
		if(null == inputStream) {
			return null;
		}
		
		String result = null;

		try {
			result = IOUtils.toString(inputStream, CONTENT_CHARSET);
		} catch (IOException e) {
			LOGGER.error("转换 HTTP 响应数据 - 失败！", e);
		}
		
		LOGGER.info("========================================");
		LOGGER.info("getArray response = " + result);
		LOGGER.info("========================================");
		
		if(null != inputStream) {
			try {
				inputStream.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 输入流 - 失败：", e);
			}
		}
		if(null != closeableHttpResponse){
			try {
				closeableHttpResponse.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 响应信息 - 失败：", e);
			}
		}  
		
		if(StringUtils.isBlank(result)) {
			return null;
		}
		
		LOGGER.info("HTTP Response Result = " + result);             
		
		if(new JsonValidator().validate(result)) {
			return JSONArray.parseArray(result, object);
		} else {
			return null;
		}
	}
	
	public Object postArray(String url, Map<String, String> parameterMap, Class<?> clazz){
		// 1.校验参数
		if(StringUtils.isBlank(url) || null == parameterMap || null == clazz) {
			return null;
		}
				
		// 2.设置请求的参数
		StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(parameterMap), CONTENT_CHARSET);     
		stringEntity.setContentEncoding(CONTENT_CHARSET);
		stringEntity.setContentType(CONTENT_TYPE_JSON_CHARSET);//发送json数据需要设置contentType
		
		// 3.配置 HTTP POST 请求
		HttpPost httpPost = new HttpPost(url);
    	//httpPost.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 180000);		// 设置“请求超时时间”
    	//httpPost.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);		// 设置“读取超时时间”
		RequestConfig
        requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(180000).build();
        httpPost.setConfig(requestConfig);
    	httpPost.setEntity(stringEntity);

        CloseableHttpClient closeableHttpClient = httpConnectionManager.getHttpClient();
        CloseableHttpResponse closeableHttpResponse = null;

        try {
        	closeableHttpResponse = closeableHttpClient.execute(httpPost);
        } catch (ClientProtocolException e) {
        	LOGGER.error("执行 HTTP POST 请求之客户端协议 - 错误！", e);
        } catch (IOException e) {
        	LOGGER.error("执行 HTTP POST 请求之输入输出 - 错误！", e);
        } 
        
        if(null == closeableHttpResponse || null == closeableHttpResponse.getStatusLine() || closeableHttpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
        	return null;
        }

      	InputStream inputStream = null; 
      	try {
			inputStream = closeableHttpResponse.getEntity().getContent();
		} catch (UnsupportedOperationException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之不支持的操作 - 错误！", e);
		} catch (IOException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之输入输出 - 错误！", e);
		}
      	
      	if(null == inputStream) {
			return null;
		}
      	
      	String result = null;
      	
      	try {
			result = IOUtils.toString(inputStream, CONTENT_CHARSET);
		} catch (IOException e) {
			LOGGER.error("转换 HTTP 响应数据 - 失败！", e);
		}
      	
		if(StringUtils.isBlank(result)) {
			return null;
		}
		
		LOGGER.info("========================================");
		LOGGER.info("postArray response = " + result);
		LOGGER.info("========================================");
		
		if(null != inputStream) {
			try {
				inputStream.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 输入流 - 失败：", e);
			}
		}
		if(null != closeableHttpResponse){
			try {
				closeableHttpResponse.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 响应信息 - 失败：", e);
			}
		}  
		
		if(new JsonValidator().validate(result)) {
			return JSONArray.parseArray(result, clazz);
		} else {
			return null;
		}
	}

	public Object postObject(String url, Map<String, String> parameterMap, Class<?> clazz){
		// 1.校验参数
		if(StringUtils.isBlank(url) || null == parameterMap || null == clazz) {
			return null;
		}
		
		// 2.设置请求的参数
		StringEntity stringEntity = new StringEntity(JSONObject.toJSONString(parameterMap), CONTENT_CHARSET);     
		stringEntity.setContentEncoding(CONTENT_CHARSET);
		stringEntity.setContentType(CONTENT_TYPE_JSON_CHARSET);//发送json数据需要设置contentType
		
		// 3.配置 HTTP POST 请求
		HttpPost httpPost = new HttpPost(url);
		//httpPost.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 180000);		// 设置“请求超时时间”
		//httpPost.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);		// 设置“读取超时时间”
		RequestConfig
        requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(180000).build();
        httpPost.setConfig(requestConfig);
		httpPost.setEntity(stringEntity);
		
		CloseableHttpClient closeableHttpClient = httpConnectionManager.getHttpClient();
		CloseableHttpResponse closeableHttpResponse = null;
		
		try {
			closeableHttpResponse = closeableHttpClient.execute(httpPost);
		} catch (ClientProtocolException e) {
			LOGGER.error("执行 HTTP POST 请求之客户端协议 - 错误！", e);
		} catch (IOException e) {
			LOGGER.error("执行 HTTP POST 请求之输入输出 - 错误！", e);
		} 
		
		if(null == closeableHttpResponse || null == closeableHttpResponse.getStatusLine() || closeableHttpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
			return null;
		}
		
		InputStream inputStream = null; 
		try {
			inputStream = closeableHttpResponse.getEntity().getContent();
		} catch (UnsupportedOperationException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之不支持的操作 - 错误！", e);
		} catch (IOException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之输入输出 - 错误！", e);
		}
		
		if(null == inputStream) {
			return null;
		}
		
		String result = null;
		
		try {
			result = IOUtils.toString(inputStream, CONTENT_CHARSET);
		} catch (IOException e) {
			LOGGER.error("转换 HTTP 响应数据 - 失败！", e);
		}
		
		if(StringUtils.isBlank(result)) {
			return null;
		}
		
		LOGGER.info("========================================");
		LOGGER.info("postObject response = " + result);
		LOGGER.info("========================================");
		
		if(null != inputStream) {
			try {
				inputStream.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 输入流 - 失败：", e);
			}
		}
		if(null != closeableHttpResponse){
			try {
				closeableHttpResponse.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 响应信息 - 失败：", e);
			}
		}  
		
		if(new JsonValidator().validate(result)) {
			return JSONObject.parseObject(result, clazz);
		} else {
			return null;
		}
	}
	
	/**
	 * POST 请求
	 * @param url 
	 * @param parameterList
	 * @param clazz
	 * @return
	 */
	public <T> T post(String url, List<NameValuePair> parameterList, Class<T> clazz){
		// 1.校验参数
		if(StringUtils.isBlank(url) || null == parameterList || null == clazz) {
			return null;
		}
		
		// 2.设置请求的参数
        HttpEntity httpEntity = null;
        try {
			httpEntity = new UrlEncodedFormEntity(parameterList, CONTENT_CHARSET);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("不支持的字符编码！", e);
		}
		
        // 3.HTTP POST 请求配置
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(180000).build();

        // 4.配置 HTTP POST 请求
		HttpPost httpPost = new HttpPost(url);
		httpPost.setConfig(requestConfig);
		httpPost.setEntity(httpEntity);
		
		CloseableHttpClient closeableHttpClient = httpConnectionManager.getHttpClient();
		CloseableHttpResponse closeableHttpResponse = null;
		
		try {
			closeableHttpResponse = closeableHttpClient.execute(httpPost);
		} catch (ClientProtocolException e) {
			LOGGER.error("执行 HTTP POST 请求之客户端协议 - 错误！", e);
		} catch (IOException e) {
			LOGGER.error("执行 HTTP POST 请求之输入输出 - 错误！", e);
		} 
		
		if(null == closeableHttpResponse || null == closeableHttpResponse.getStatusLine() || closeableHttpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
			return null;
		}
		
		String result = null;
		
		 try {
			 result = EntityUtils.toString(closeableHttpResponse.getEntity());
			System.out.println();
		} catch (ParseException | IOException e) {
			LOGGER.error("解析 HTTP POST 响应 - 失败！", e);
		}
		 
		if(StringUtils.isBlank(result)) {
			return null;
		}
		
		LOGGER.info("========================================");
		LOGGER.info("POST 返回值： " + result);
		LOGGER.info("========================================");
		
		if(null != closeableHttpResponse){
			try {
				closeableHttpResponse.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 响应信息 - 失败：", e);
			}
		}  
		
		if(new JsonValidator().validate(result)) {
			return JSONObject.parseObject(result, clazz);
		} else {
			return null;
		}
	}

    /**
     * 封装 Http post请求
     * @param url 请求URL路径
     * @param params post请求参数
     * @param clazz 返回指定类型
     * @return
     */
    public <T> T post(String url,Map<String, String> params,Class<T> clazz){
    	
    	CloseableHttpClient httpClient=httpConnectionManager.getHttpClient();
    	CloseableHttpResponse response=null;
    	String json=null;
    	try {
    		response = httpClient.execute(buildHttpPost(url,params));
    		HttpEntity entity = response.getEntity();
    		InputStream in=entity.getContent();
    		json=IOUtils.toString(in, CONTENT_CHARSET);
            in.close();
            /*
            in.close();
            	作用就是将用完的连接释放，下次请求可以复用，这里特别注意的是，
            	如果不使用in.close();而仅仅使用response.close();
            	结果就是连接会被关闭，并且不能被复用，这样就失去了采用连接池的意义
            if (entity != null) {
                String returnStr = EntityUtils.toString(entity,charset);
                return returnStr;
            }
            */
    	} catch (UnsupportedOperationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
			e.printStackTrace();
		}finally {
        	if(response!=null){
            	try {
            		response.close();
            	} catch (IOException e) {
            		e.printStackTrace();
            	}
            }
        }
    	return JSON.parseObject(json, clazz);
    }
    
    
    /**
     * post发送json
     * @param url
     * @param parameterJSONObject
     * @return
     */
	public <T> T httpPostWithJson(String url, JSONObject parameterJSONObject, Class<T> clazz){
		// 1.校验参数
		if(StringUtils.isBlank(url) || null == parameterJSONObject || null == clazz) {
			return null;
		}
		
		// 2.设置请求的参数
		StringEntity stringEntity = new StringEntity(parameterJSONObject.toString(), CONTENT_CHARSET);     
		stringEntity.setContentEncoding(CONTENT_CHARSET);
		stringEntity.setContentType(CONTENT_TYPE_JSON_CHARSET);//发送json数据需要设置contentType
    	
		// 3.配置 HTTP POST 请求
		HttpPost httpPost = new HttpPost(url);
    	//httpPost.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 180000);		// 设置“请求超时时间”
    	//httpPost.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);		// 设置“读取超时时间”
		RequestConfig
        requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(180000).build();
        httpPost.setConfig(requestConfig);
    	httpPost.setEntity(stringEntity);

        CloseableHttpClient closeableHttpClient = httpConnectionManager.getHttpClient();
        CloseableHttpResponse closeableHttpResponse = null;

        try {
        	closeableHttpResponse = closeableHttpClient.execute(httpPost);
        } catch (ClientProtocolException e) {
        	LOGGER.error("执行 HTTP POST 请求之客户端协议 - 错误！", e);
        } catch (IOException e) {
        	LOGGER.error("执行 HTTP POST 请求之输入输出 - 错误！", e);
        } 
        
        if(null == closeableHttpResponse || null == closeableHttpResponse.getStatusLine() || closeableHttpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
        	return null;
        }

      	InputStream inputStream = null; 
      	try {
			inputStream = closeableHttpResponse.getEntity().getContent();
		} catch (UnsupportedOperationException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之不支持的操作 - 错误！", e);
		} catch (IOException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之输入输出 - 错误！", e);
		}
      	
      	if(null == inputStream) {
			return null;
		}
      	
      	String result = null;
      	
      	try {
			result = IOUtils.toString(inputStream, CONTENT_CHARSET);
		} catch (IOException e) {
			LOGGER.error("转换 HTTP 响应数据 - 失败！", e);
		}
      	
      	LOGGER.info("========================================");
		LOGGER.info("httpPostWithJson response = " + result);
		LOGGER.info("========================================");
		
		if(StringUtils.isBlank(result)) {
			return null;
		}

      	T response = JSON.parseObject(result, clazz);;

      	if(null != inputStream) {
      		try {
      			inputStream.close();
      		} catch (IOException e) {
      			LOGGER.error("关闭输入流 - 失败！", e);
      		}
      	}
      	
      	if(null != closeableHttpResponse) {
      		try {
				closeableHttpResponse.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 响应流 - 失败！", e);
			}
      	}
      	
      	return response;
    }

	/**
	 * 发送 POST 请求
	 * @param url
	 * @param parameter4JSON
	 * @param clazz
	 * @return
	 */
	public <T> T post(String url, String parameter4JSON, Class<T> clazz){
		LOGGER.info("parameter4JSON = {}", parameter4JSON);
		// 1.校验参数
		if(StringUtils.isBlank(parameter4JSON) || null == clazz) {
			return null;
		}
		
		// 2.设置请求的参数
		StringEntity stringEntity = new StringEntity(parameter4JSON, CONTENT_CHARSET);     
		stringEntity.setContentEncoding(CONTENT_CHARSET);
//		stringEntity.setContentType(CONTENT_TYPE_JSON_CHARSET);//发送json数据需要设置contentType
//		stringEntity.setContentType("application/plain; charset=utf-8");//发送json数据需要设置contentType
		stringEntity.setContentType("text/plain; charset=utf-8");//发送json数据需要设置contentType
		
		// 3.配置 HTTP POST 请求
		HttpPost httpPost = new HttpPost(url);
		//httpPost.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 180000);		// 设置“请求超时时间”
		//httpPost.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 60000);		// 设置“读取超时时间”
		RequestConfig
		requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(180000).build();
		httpPost.setConfig(requestConfig);
		httpPost.setEntity(stringEntity);
		
		CloseableHttpClient closeableHttpClient = httpConnectionManager.getHttpClient();
		CloseableHttpResponse closeableHttpResponse = null;
		
		try {
			closeableHttpResponse = closeableHttpClient.execute(httpPost);
		} catch (ClientProtocolException e) {
			LOGGER.error("执行 HTTP POST 请求之客户端协议 - 错误！", e);
		} catch (IOException e) {
			LOGGER.error("执行 HTTP POST 请求之输入输出 - 错误！", e);
		} 
		
		if(null == closeableHttpResponse || null == closeableHttpResponse.getStatusLine() || closeableHttpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
			return null;
		}
		
		InputStream inputStream = null; 
		try {
			inputStream = closeableHttpResponse.getEntity().getContent();
		} catch (UnsupportedOperationException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之不支持的操作 - 错误！", e);
		} catch (IOException e) {
			LOGGER.error("HTTP POST 请求之获取响应结果之输入输出 - 错误！", e);
		}
		
		if(null == inputStream) {
			return null;
		}
		
		String result = null;
		
		try {
			result = IOUtils.toString(inputStream, CONTENT_CHARSET);
		} catch (IOException e) {
			LOGGER.error("转换 HTTP 响应数据 - 失败！", e);
		}
		
		LOGGER.info("========================================");
		LOGGER.info("post response = " + result);
		LOGGER.info("========================================");
		
		if(StringUtils.isBlank(result)) {
			return null;
		}
		
		T response = JSON.parseObject(result, clazz);;
		
		if(null != inputStream) {
			try {
				inputStream.close();
			} catch (IOException e) {
				LOGGER.error("关闭输入流 - 失败！", e);
			}
		}
		
		if(null != closeableHttpResponse) {
			try {
				closeableHttpResponse.close();
			} catch (IOException e) {
				LOGGER.error("关闭 HTTP 响应流 - 失败！", e);
			}
		}
		
		return response;
	}

    public <T> T httpPostWithJson2(String url,JSONObject json,Class<T> clazz){
        CloseableHttpClient client=httpConnectionManager.getHttpClient();
          HttpPost post = new HttpPost(url);
          T response = null;
          CloseableHttpResponse res = null;
          try {
            StringEntity s = new StringEntity(json.toString(),CONTENT_CHARSET);     
            s.setContentEncoding(CONTENT_CHARSET);
            s.setContentType(CONTENT_TYPE_JSON_CHARSET);//发送json数据需要设置contentType
            post.setEntity(s);
            res = client.execute(post);
            if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
            	//HttpEntity entity = res.getEntity();
            	InputStream in=res.getEntity().getContent();
        		String jsonstr=IOUtils.toString(in, CONTENT_CHARSET);
        		//String result = EntityUtils.toString(res.getEntity());// 返回json格式：
        		in.close();
        		if(jsonstr.contains("\"result\":\"[]\""))
        		return null;
        		response = JSON.parseObject(jsonstr, clazz);
            }
          } catch (Exception e) {
            throw new RuntimeException(e);
          }finally {
          	if(res!=null){
            	try {
            		res.close();
            	} catch (IOException e) {
            		e.printStackTrace();
            	}
            }
        }
          return response;
        }

    /*public static void main(String[] args) {
    	HttpClientUtil httpClientUtil = new HttpClientUtil();
    	String url = "http://testcoupon.artup.com/artup-coupon-api/f/queryCoupon";
    	Map<String, String> parameterMap = new HashMap<String, String>();
    	parameterMap.put("couponCode", "1ybln9n4qvPJ");
    	Map<String, Object> resultMap = httpClientUtil.getMap(url, parameterMap);
    	System.out.println(resultMap);
	}*/

    @SuppressWarnings({ "resource" })
	public static void main(String[] args) throws URISyntaxException, ClientProtocolException, IOException {  
        
        //核心应用类   
        HttpClient httpClient = new DefaultHttpClient();  
          
        //设定表单需要提交的参数  
        List<NameValuePair> qparams = new ArrayList<NameValuePair>();  
          
        //示例：提交用户名和密码  
        qparams.add(new BasicNameValuePair("data", "{'item_count':'0','shipping_total':'0.0','order_created':'Wed Aug 09 18:22:40 CST 2017','buy_county':'海淀区','buy_address':'','item_total':'20170809182239711106009969890358','pay_total':'null','buy_city':'北京市','source':'ios','buy_province':'北京','buy_email':'20170809182239711106009969890358','ifinvoice':'0','buy_name':'Hapday','total':'399.0','shipping_name':'顺丰','order_id':'20170809182239711106009969890358','buy_tel':''}"));  
//        qparams.add(new BasicNameValuePair("myPassword", "password"));  
          
        //设定需要访问的URL，第四个参数为表单提交路径  
        URI uri = URIUtils.createURI("http", "testmes.artup.com", -1, "/serve/saveOrderInfo",  
        //将参数加入URL中  
        URLEncodedUtils.format(qparams, "UTF-8"), null);  
        //Post提交  
        HttpPost httpPost = new HttpPost(uri);  
          
        //System.out.println(httpPost.getURI());  
          
        //httpClient执行，返回response  
        HttpResponse response = httpClient.execute(httpPost);  
          
        //获取实体  
        HttpEntity httpEntity= response.getEntity();  
             
        //打印StatusLine  
        System.out.println("StatusLine: " + response.getStatusLine());  
          
        //读取内容   
        String content = EntityUtils.toString(httpEntity, "UTF-8");  
        //打印输出结果内容  
        System.out.println(content);  
  
    }  
    
    @SuppressWarnings({ "resource" })
	public static void post(String domainName, String methomdName, List<NameValuePair> requestParametes) throws URISyntaxException, ClientProtocolException, IOException {  
    	//核心应用类   
    	HttpClient httpClient = new DefaultHttpClient();  
    	
    	//设定需要访问的URL，第四个参数为表单提交路径  
    	// 将参数加入URL中
		URI uri = URIUtils.createURI("http", domainName, -1, methomdName, URLEncodedUtils.format(requestParametes, "UTF-8"), null);  
    	//Post提交  
    	HttpPost httpPost = new HttpPost(uri);  
    	
    	//httpClient执行，返回response  
    	HttpResponse response = httpClient.execute(httpPost);  
    	
    	//获取实体  
    	HttpEntity httpEntity= response.getEntity();  
    	
    	//打印StatusLine  
    	System.out.println("StatusLine: " + response.getStatusLine());  
    	
    	//读取内容   
    	String content = EntityUtils.toString(httpEntity, "UTF-8");  
    	//打印输出结果内容  
    	System.out.println(content);  
    }
}
